#include "stdafx.h"
#include "AsyncHttpUtils.h"
using namespace rjksClient;

AsyncHttpUtils::AsyncHttpUtils(void)
{
}

AsyncHttpUtils::AsyncHttpUtils(String^ server)
{
	this->frmNetworkBusyInstance=gcnew frmNetworkBusy;
}
Stream^ AsyncHttpUtils::GetSimpleGETResponse(String^ url,Action<int>^ Callback)
{
	HttpWebRequest^ request = (HttpWebRequest^) WebRequest::Create("http://"+server+":"+port+"/"+url);  
    request->Method = "GET";
	request->Timeout=timeout*1000;
	if(cookie->Length>0)
		request->Headers->Add("Cookie",cookie);
    HttpWebResponse^ resp= (HttpWebResponse^) request->GetResponse(); 
	Stream^ mem = gcnew MemoryStream();
	Stream^ in =resp->GetResponseStream();
	//Stream^ outStream =System::IO::File::Create( saveFileDialog1->FileName );
	//BinaryWriter^ bw = gcnew BinaryWriter(fs);
	array<Byte>^buf = gcnew array<Byte>(CHUNK_SIZE_DOWNLOAD);
	long total=resp->ContentLength;
	int osize=1;
	double readsize=0.0;
	while(osize>0)
	{
		//MessageBox::Show(readsize.ToString()+","+total.ToString()+","+(readsize/total*100).ToString());
		osize=in->Read(buf,0,CHUNK_SIZE_DOWNLOAD);
		mem->Write(buf,0,osize);
		readsize+=buf->Length;
		Callback(readsize/total*100);
		Application::DoEvents();
	}
	in->Close();
	mem->Position=0;
	return mem;
}

JObject^ AsyncHttpUtils::GetFileUploadResponse(String^ url,String^ filepath, Action<int>^ Callback)
{
	int returnValue = 0;
    FileStream^ fs = gcnew FileStream(filepath, FileMode::Open, FileAccess::Read); 
    BinaryReader^ br = gcnew BinaryReader(fs);
    String^ strBoundary = "----------" + DateTime::Now.Ticks.ToString("x"); 
    array<Byte>^ boundaryBytes = Encoding::ASCII->GetBytes("\r\n--" + strBoundary + "\r\n");
    StringBuilder^ sb = gcnew StringBuilder(); 
    sb->Append("--"+strBoundary+
		"\r\nContent-Disposition: form-data; name=\"file\"; filename=\""+Path::GetFileName(filepath)+
		"\"\r\nContent-Type: "+GetMIMEType(filepath)+
		"\r\n\r\n"); 
    String^ strPostHeader = sb->ToString(); 
    array<Byte>^ postHeaderBytes = Encoding::UTF8->GetBytes(strPostHeader);
    HttpWebRequest^ httpReq = (HttpWebRequest^)WebRequest::Create("http://"+server+":"+port+"/"+url+"?filename="+Utils::Urlencode(Path::GetFileName(filepath))); 
    httpReq->Method = "POST";
	httpReq->Timeout=timeout*1000;
	if(cookie->Length>0)
		httpReq->Headers->Add("Cookie",cookie);
    httpReq->AllowWriteStreamBuffering = false;
    httpReq->Timeout = 300000;
    httpReq->ContentType = "multipart/form-data; boundary=" + strBoundary; 
    long length = fs->Length + postHeaderBytes->Length ;//+ boundaryBytes->Length; 
    long fileLength = fs->Length; 
    httpReq->ContentLength = length; 
    array<Byte>^ buffer = gcnew array<Byte>(CHUNK_SIZE_UPLOAD);
    float bytesread = 0;
	int size = br->Read(buffer, 0, CHUNK_SIZE_UPLOAD); 
    Stream^ postStream = httpReq->GetRequestStream();
    postStream->Write(postHeaderBytes, 0, postHeaderBytes->Length); 
    while (size > 0) 
    { 
        postStream->Write(buffer, 0, size); 
        bytesread += size; 
		Callback(bytesread/fileLength*100);
        Application::DoEvents(); 
        size = br->Read(buffer, 0, CHUNK_SIZE_UPLOAD); 
    } 
    //postStream->Write(boundaryBytes, 0, boundaryBytes->Length); 
    postStream->Close();
    WebResponse^ webRespon = httpReq->GetResponse(); 
    Stream^ resp = webRespon->GetResponseStream(); 
    String^ sReturnString = (gcnew StreamReader(resp))->ReadLine(); 
    resp->Close(); 
    fs->Close(); 
    br->Close(); 
    return gcnew JObject(); 
}

JObject^ AsyncHttpUtils::GetResponse(String^ url)
{
	return GetResponse(url,gcnew String(""),true);
}

JObject^ AsyncHttpUtils::GetResponse(String^ url, bool ShowError){
	return GetResponse(url,gcnew String(""),ShowError);
}

void AsyncHttpUtils::ThreadDo(System::Object^ obj)
{
	String^ url=((ThreadHelper^)obj)->url;
	String^ postdata=((ThreadHelper^)obj)->postdata;
	HttpWebRequest^ request ;
	try{
		request= (HttpWebRequest^) WebRequest::Create("http://"+server+":"+port+"/"+url);  
	}catch(Exception^ ex){
		((ThreadHelper^)obj)->haserror=true;
		((ThreadHelper^)obj)->ret=JObject::Parse("{\"msg\":\""+ex->Message+"\",\"err\":1}");
		return;
	}
	if(cookie->Length>0)
	request->Headers->Add("Cookie",cookie);
	request->Timeout=timeout*1000;
	if (postdata->Length>0)
	{
		request->Method = "POST"; 
		request->ContentLength = postdata->Length;
		request->ContentType="application/x-www-form-urlencoded;charset=utf-8";
		Stream^ requestStream;
		try
		{
			 requestStream = request->GetRequestStream();
		}catch (WebException^ ex)
		{
			((ThreadHelper^)obj)->haserror=true;
			((ThreadHelper^)obj)->ret=JObject::Parse("{\"msg\":\""+ex->Message+"\"}");
			return;
		}
		array<Byte>^ abyte= Encoding::GetEncoding("ascii")->GetBytes(postdata);
        requestStream->Write(abyte, 0, abyte->Length);
        requestStream->Close();
	}else
		request->Method = "GET";  
	HttpWebResponse^ resp;
	try
	{
		resp= (HttpWebResponse^) request->GetResponse();  
	}catch (WebException^ ex)
	{
		((ThreadHelper^)obj)->haserror=true;
		((ThreadHelper^)obj)->ret=JObject::Parse("{\"msg\":\""+ex->Message+"\",\"err\":1}");
		return;
	}
	if(resp->Headers->Get("Set-cookie")!=nullptr)
		cookie = resp->Headers->Get("Set-cookie");
	StreamReader^ reader = gcnew StreamReader(resp->GetResponseStream(), Encoding::UTF8);
	String^ ret=reader->ReadToEnd();
	//MessageBox::Show(ret);
	((ThreadHelper^)obj)->ret=JObject::Parse(ret);
	((ThreadHelper^)obj)->ret->Add("err",0);
	return ;//JObject::Parse(ret);
}

JObject^ AsyncHttpUtils::GetResponse(String^ url, String^ PostData)
{
	return 	GetResponse(url, PostData,true);
}
JObject^ AsyncHttpUtils::GetResponse(String^ url, String^ PostData,bool ShowError){
	ThreadHelper^ th=gcnew ThreadHelper(url,PostData);
	Thread^ WorkThread = gcnew Thread(gcnew ParameterizedThreadStart(ThreadDo));
	WorkThread->Start(th);
	while(WorkThread->IsAlive)
	{
		System::Threading::Thread::Sleep(50);
		Application::DoEvents();
	}
	if(th->haserror&&ShowError)
		(gcnew frmMsgBox)->ShowError(((JObject^)(th->ret))["msg"]->ToString());
	return th->ret;
}
JObject^ AsyncHttpUtils::GetResponse(String^ url, Action<JObject^>^ Callback)
{
	JObject^ ret= GetResponse(url,gcnew String(""),Callback);
	return ret;
}

JObject^ AsyncHttpUtils::GetResponse(String^ url, String^ PostData, Action<JObject^>^ Callback)
{
	JObject^ ret= GetResponse(url, PostData);
	Callback(ret);
	return ret;
}

JObject^ AsyncHttpUtils::GetBlockdaResponse(String^ url)
{
	return GetBlockdaResponse(url,gcnew String(""));
}

JObject^ AsyncHttpUtils::GetBlockdaResponse(String^ url, String^ PostData)
{
	frmNetworkBusy^ frmNetworkBusyInstance=gcnew frmNetworkBusy;
	frmNetworkBusyInstance->FadeIn();
	ThreadHelper^ th=gcnew ThreadHelper(url,PostData);
	Thread^ WorkThread = gcnew Thread(gcnew ParameterizedThreadStart(ThreadDo));
	WorkThread->Start(th);
	while(WorkThread->IsAlive)
	{
		System::Threading::Thread::Sleep(50);
		Application::DoEvents();
	}
	frmNetworkBusyInstance->FadeOut();
	if(th->haserror)
		(gcnew frmMsgBox)->ShowError(((JObject^)(th->ret))["msg"]->ToString());
	return th->ret;
}

JObject^ AsyncHttpUtils::GetBlockdaResponse(String^ url, Action<JObject^>^ Callback)
{
	return GetBlockdaResponse(url,gcnew String(""), Callback);
}

JObject^ AsyncHttpUtils::GetBlockdaResponse(String^ url, String^ PostData, Action<JObject^>^ Callback)
{
	JObject^ ret=GetBlockdaResponse(url,PostData);
	Callback(ret);
	return ret;
}



 String^ AsyncHttpUtils::GetMIMEType(String^ filename)
{
	int pos =Array::IndexOf(_mappings,Path::GetExtension(filename));
	if(pos==-1)
		return "application/octet-stream";
	else
		return _mappings[pos+1];
}